#pragma once
#include"mylog.hpp"
#include"Addr.hpp"
#include"common.hpp"
using namespace my_log;
int defaultsockfd=-1;
class tcpserver:public nocopy
{
public:
    tcpserver(uint16_t port)
    :_port(port),_sockfd(defaultsockfd),_isrunning(false)
    {}
    void Init()
    {
        //首先创建异端
        _sockfd=socket(AF_INET,SOCK_STREAM,0);
        if(_sockfd==-1)
        {
            //创建异端失败
            LOG(LogLevel::FATAL)<<"异端创建失败!";
            exit(Sock::sockerr);
        }
        LOG(LogLevel::DEBUG)<<"异端创建成功,fd:"<<_sockfd;
        //建立绑定
        Addr peer(_port);
        int n=bind(_sockfd,(struct sockaddr*)peer.pSockaddr(),peer.Socklen());
        if(n==-1)
        {
            //绑定失败
            LOG(LogLevel::FATAL)<<"异端绑定失败!";
            exit(Sock::binderr);
        }
        LOG(LogLevel::DEBUG)<<"异端绑定成功,fd="<<_sockfd;
        //设置为listen状态
        int lis=listen(_sockfd,8);
        if(lis==-1)
        {
            LOG(LogLevel::FATAL)<<"监听状态设置失败!";
            exit(Sock::listenerr);
        }
        LOG(LogLevel::DEBUG)<<"监听状态设置成功,fd="<<_sockfd;
    }
    void Service(int sockfd,Addr& client)
    {
        char buffer[1024];
        while(true)
        {
            ssize_t n=read(sockfd,buffer,sizeof(buffer)-1);
            if(n>0)
            {
                //消息接收成功
                buffer[n]=0;//设置为字符串风格
                //cout<<"this is buffer:"<<buffer;
                LOG(LogLevel::DEBUG)<<client.GetAddr()<<"says@"<<buffer;
                //echo
                std::string buf=buffer;
                std::string message="server echos@"+buf+'\n';
                int w=write(sockfd,message.c_str(),message.size());
            }
            else if(n==0)
            {
                //客户关闭连接,读取到文件结尾
                LOG(LogLevel::DEBUG)<<client.GetAddr()<<"退出...";
                close(sockfd);
                break;
            }
            else
            {
                LOG(LogLevel::FATAL)<<client.GetAddr()<<"异常!";
                close(sockfd);
                break;
            }
        }
    }
    void Start()
    {
        _isrunning=true;
        while(_isrunning)
        {
            struct sockaddr_in cli;
            cli.sin_family=AF_INET;
            socklen_t len=sizeof(cli);
            int sockfd=accept(_sockfd,(struct sockaddr*)&(cli),&len);
            if(sockfd<0)
            {
                LOG(LogLevel::FATAL)<<"accpet失败!";
                continue;
            }
            Addr client(cli);
            LOG(LogLevel::DEBUG)<<client.GetAddr()<<"用户上线!";
            Service(sockfd,client);
        }
        _isrunning=false;
    }
    ~tcpserver()
    {}
private:
    uint16_t _port;
    int _sockfd;
    bool _isrunning;
};